/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.ac.iie.ulss.indexer.writer;

import cn.ac.iie.ulss.indexer.runenvs.Constants;
import cn.ac.iie.ulss.indexer.runenvs.GlobalParas;
import java.io.File;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.LogByteSizeMergePolicy;
import org.apache.lucene.index.TieredMergePolicy;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

/**
 *
 * 
 */
public class LuceneWriterUtil {

    public static Logger log = Logger.getLogger(LuceneWriterUtil.class.getName());

    public static IndexWriter getSimpleLuceneWriter(String path, boolean isNew, String tb) {
        IndexWriter FSWriter = null;
        try {
            File f = new File(path);
            if (!f.getParentFile().exists()) {
                f.getParentFile().mkdirs();
            }
            Directory dir = FSDirectory.open(f);
            Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_42);
            IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_42, analyzer);

            LuceneConfig c = GlobalParas.luceneConfigMap.get(tb);
            if (c == null) {
                c = GlobalParas.luceneConfigMap.get(Constants.writer_default_config);
            }
            conf.setMaxThreadStates(GlobalParas.luceneMaxThreadStates);
            conf.setMaxBufferedDocs(c.getLuceneBufferDocs());
            conf.setRAMBufferSizeMB(c.getLuceneBufferRam());

            if (GlobalParas.mergePolicy.equalsIgnoreCase("logbyte")) {
                LogByteSizeMergePolicy mergePolicy = new LogByteSizeMergePolicy();
                mergePolicy.setMaxMergeDocs(c.getMergePolicyMaxMergeDocs());
                mergePolicy.setMinMergeMB(c.getMergePolicyMinMergeMB());
                mergePolicy.setMaxMergeMB(c.getMergePolicyMaxMergeMB());
                mergePolicy.setMergeFactor(c.getMergePolicyMergeFactor());
                mergePolicy.setUseCompoundFile(true);//注意如何设置使用复合索引结构，减小打开的文件数量
                mergePolicy.setMaxMergeMBForForcedMerge(c.getMaxMergeMB_Forcemerge()); //in MB,段的大小超过限制就不再forcemerge阶段merge掉，保留多个段，防止merge的代价过大（有些情况下单个lucene文件的大小会超过20G）

                conf.setMergePolicy(mergePolicy);
                log.info("use logbyte mergePolicy " + mergePolicy + " for " + tb);
            } else if (GlobalParas.mergePolicy.equalsIgnoreCase("Tiered")) {
                log.info("use tiered mergePolicy ");
            } else if (GlobalParas.mergePolicy.equalsIgnoreCase("default")) {
                log.info("use default mergePolicy " + conf.getMergePolicy());
            } else {
                log.info("unknown mergePolicy,will exit ....");
                System.exit(0);
            }
            //ConcurrentMergeScheduler cms = new ConcurrentMergeScheduler();
            conf.setMaxThreadStates(GlobalParas.luceneMaxThreadStates);
            conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
            if (IndexWriter.isLocked(dir) && isNew) {
                log.warn("this is the second time for the file " + path + " to create,has something wrong ? ");
                FSWriter = null;
            } else if (IndexWriter.isLocked(dir) && !isNew) {
                log.info("the lucene dir " + dir + " is locked, will unlock it," + "the lock id is " + dir.getLockID());
                IndexWriter.unlock(dir);
                FSWriter = new IndexWriter(dir, conf);
            } else if (!IndexWriter.isLocked(dir) && isNew) {
                FSWriter = new IndexWriter(dir, conf);
            } else if (!IndexWriter.isLocked(dir) && !isNew) {
                FSWriter = new IndexWriter(dir, conf);
            }
        } catch (Exception ex) {
            //假如只读
            FSWriter = null;
            log.error(ex, ex);
        }
        return FSWriter;
    }

    public static IndexWriter testGetSimpleLuceneWriter(String path) {
        IndexWriter FSWriter = null;
        try {
            File f = new File(path);
            if (!f.getParentFile().exists()) {
                f.getParentFile().mkdirs();
            }
            Directory dir = FSDirectory.open(f);
            Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_42);
            IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_42, analyzer);
            conf.setMaxBufferedDocs(1000000);
            conf.setRAMBufferSizeMB(100);
            conf.setMaxThreadStates(12);

            conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
            ((TieredMergePolicy) conf.getMergePolicy()).setUseCompoundFile(true);//注意如何设置使用复合索引结构，减小打开的文件数量

            if (IndexWriter.isLocked(dir)) {
                log.info("the lucene dir " + dir + " is locked, will unlock it," + "the lock id is " + dir.getLockID());
                IndexWriter.unlock(dir);
                FSWriter = new IndexWriter(dir, conf);
            } else if (!IndexWriter.isLocked(dir)) {
                FSWriter = new IndexWriter(dir, conf);
            }
        } catch (Exception ex) {
            //假如只读或者磁盘其他什么情况
            FSWriter = null;
            log.error(ex, ex);
        }
        return FSWriter;
    }

    public static void createsFile(String path) throws IOException {
        File file = new File(path);
        File parent = file.getParentFile();
        if (parent != null && !parent.exists()) {
            parent.mkdirs();
        }
        file.createNewFile();
    }

    public static void main(String[] args) {
        try {
            System.out.println(" sdfjds fdsdfds ".replace(" ", "").replace("", ""));
            IndexWriter FSWriter = LuceneWriterUtil.testGetSimpleLuceneWriter(".\\123456");
            FSWriter.commit();
        } catch (Exception ex) {
            System.out.println(ex);
        }

//        File f = new File(".\\asd\\p\\q\\r");
//        if (!f.getParentFile().exists()) {
//            f.getParentFile().mkdirs();
//        }

    }
}
